﻿using Engine;
using Engine.Graphics;

namespace Game
{
    public class BuffParticleSystem : ParticleSystem<BuffParticleSystem.Particle>
    {
        public class Particle : Game.Particle
        {
            public float Time;

            public float Duration;

            public Vector3 Velocity;
        }

        private Random m_random = new Random();

        private float m_toGenerate;

        private bool m_visible;

        public bool IsStopped { get; set; }

        public Vector3 Position { get; set; }

        public Color Color { get; set; } = Color.White;


        public Vector2 Size { get; set; } = new Vector2(0.1f);


        public float Radius { get; set; }

        public float Speed { get; set; } = 2f;


        public bool MoveAble { get; set; } = true;


        public new Texture2D Texture
        {
            get
            {
                return base.Texture;
            }
            set
            {
                if (value != base.Texture)
                {
                    base.Texture = value;
                }
            }
        }

        public new int TextureSlotsCount
        {
            get
            {
                return base.TextureSlotsCount;
            }
            set
            {
                if (value != base.TextureSlotsCount)
                {
                    base.TextureSlotsCount = value;
                }
            }
        }

        public BuffParticleSystem(int particleCount = 10)
            : base(particleCount)
        {
            Texture = ContentManager.Get<Texture2D>("Textures/Star");
            TextureSlotsCount = 1;
        }

        public override bool Simulate(float dt)
        {
            bool flag = false;
            if (m_visible)
            {
                m_toGenerate += 20f * dt;
                float num = MathUtils.Pow(0.02f, dt);
                for (int i = 0; i < base.Particles.Length; i++)
                {
                    Particle particle = base.Particles[i];
                    if (particle.IsActive)
                    {
                        flag = true;
                        particle.Time += dt;
                        if (particle.Time <= particle.Duration)
                        {
                            if (MoveAble)
                            {
                                particle.Position += particle.Velocity * dt;
                                particle.Velocity *= num;
                                particle.Velocity.Y = particle.Velocity.Y + Speed * dt;
                            }
                            else
                            {
                                particle.Position += particle.Velocity * dt;
                                particle.Velocity *= num;
                            }

                            particle.Size = Size;
                            particle.TextureSlot = (int)MathUtils.Min(MathUtils.Pow(TextureSlotsCount, 2f) * particle.Time / particle.Duration * 1.2f, MathUtils.Pow(TextureSlotsCount, 2f) - 1f);
                        }
                        else
                        {
                            particle.IsActive = false;
                        }
                    }
                    else if (!IsStopped)
                    {
                        if (m_toGenerate >= 1f)
                        {
                            particle.IsActive = true;
                            if (MoveAble)
                            {
                                Vector3 vector = new Vector3(m_random.Float(-1f, 1f), m_random.Float(0f, 1f), m_random.Float(-1f, 1f));
                                particle.Position = Position + 0.75f * Radius * vector;
                                particle.Velocity = 1.5f * vector;
                                particle.Duration = m_random.Float(0.5f, 1.5f);
                            }
                            else
                            {
                                particle.Position = Position;
                                particle.Duration = 0.05f;
                            }

                            particle.Color = Color;
                            particle.Size = Size;
                            particle.Time = 0f;
                            particle.FlipX = m_random.Bool();
                            particle.FlipY = m_random.Bool();
                            m_toGenerate -= 1f;
                        }
                    }
                    else
                    {
                        m_toGenerate = 0f;
                    }
                }

                m_toGenerate = MathUtils.Remainder(m_toGenerate, 1f);
                m_visible = false;
            }

            return IsStopped && !flag;
        }

        public override void Draw(Camera camera)
        {
            if (MoveAble)
            {
                float num = Vector3.Dot(Position - camera.ViewPosition, camera.ViewDirection);
                if (num > -5f && num <= 48f)
                {
                    m_visible = true;
                    base.Draw(camera);
                }
            }
            else
            {
                m_visible = true;
                base.Draw(camera);
            }
        }
    }
}